package de.wojenko.sps;

import java.io.File;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBException;

import com.google.common.base.Function;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

public class XmlFileTaskService implements TaskService {

	private static final String DEFAULT_FILENAME = "tasks.xml";

	private final BacklogItem item;
	public final File sprintDirectory;

	public XmlFileTaskService(File rootDir, BacklogItem item) {
		this.sprintDirectory = rootDir;
		this.item = item;
	}

	@Override
	public BacklogItemArtefactHolder<Task> loadTasks() {
		Map<String, BacklogItemArtefactHolder<Task>> content = loadFile();
		if(content.containsKey(item.getId())) {
			return content.get(item.getId());
		}
		return new BacklogItemArtefactHolder<>(item.getId());
	}

	@Override
	public void storeTasks(BacklogItemArtefactHolder<Task> tasks) {
		Map<String, BacklogItemArtefactHolder<Task>> content = loadFile();
		if (content.isEmpty()) {
			content = Maps.newHashMap();
		}

		content.put(tasks.getBacklogItemNumber(), tasks);

		storeFile(content);
	}

	private Map<String, BacklogItemArtefactHolder<Task>> loadFile() {
		try {
			XmlSprintTasks sprints;
			File source = new File(sprintDirectory, DEFAULT_FILENAME);
			if (source.isFile() && source.canRead()) {
				sprints = JAXBUtils.unmarshall(XmlSprintTasks.class, source, XmlSprintTasks.class,
						XmlBacklogItemTaskHolder.class, XmlTask.class);
			} else {
				sprints = new XmlSprintTasks();
			}
			
			if(sprints.getBacklogItemTasks() == null) {
				List<XmlBacklogItemTaskHolder> list = Lists.newArrayList();
				sprints.setBacklogItemTasks(list );
			}
			
			Map<String, BacklogItemArtefactHolder<Task>> result = Maps.newHashMap();
			for (XmlBacklogItemTaskHolder holder : sprints.getBacklogItemTasks()) {
				
				BacklogItemArtefactHolder<Task> taskHolder = new BacklogItemArtefactHolder<Task>(holder.getBacklogItemId(), Lists.transform(holder.getTasks(), new Function<XmlTask, Task>() {
					@Override
					public Task apply(XmlTask input) {
						return input;
					}
				}));
				result.put(holder.getBacklogItemId(), taskHolder);	
			}

			return result;
		} catch (JAXBException e) {
			throw Throwables.propagate(e);
		}
	}

	private void storeFile(Map<String, BacklogItemArtefactHolder<Task>> content) {
		XmlSprintTasks tasks = new XmlSprintTasks();
		List<XmlBacklogItemTaskHolder> backlogItemTasks = Lists.newArrayList();
		for (BacklogItemArtefactHolder<Task> x : content.values()) {
			XmlBacklogItemTaskHolder th = new XmlBacklogItemTaskHolder();
			th.setBacklogItemId(x.getBacklogItemNumber());
			th.setTasks(Lists.transform(x, new Function<Task, XmlTask>() {
				@Override
				public XmlTask apply(Task input) {
					XmlTask result = new XmlTask();
					result.setId(input.getId());
					result.setText(input.getText());
					result.setComment(input.getComment());
					return result;
				}
			}));
			backlogItemTasks.add(th);
		}
		
		tasks.setBacklogItemTasks(backlogItemTasks );
		try {
			JAXBUtils.marshall(tasks, new File(sprintDirectory,DEFAULT_FILENAME), XmlSprintTasks.class, XmlBacklogItemTaskHolder.class, XmlTask.class);
		} catch (JAXBException e) {
			throw Throwables.propagate(e);
		}
	}
}
